#ifndef SHTO_DEFINES_H
#define SHTO_DEFINES_H
#include <string>
#include <vector>
#include <utility>
#include <list>
#include <map>
#include <set>
#include <memory>
#include <algorithm>
#include <stack>

#include <boost/shared_ptr.hpp>

#define SH_ORG_NAME "SH"
#define SH_APP_NAME "NetBoard"
#define SH_APP_VER "0.01"

// primitive types


// generic containers
template <class K, class V> struct Pair { typedef std::pair<K, V> Type; };
template <class K, class V> struct Map { typedef std::map<K, V> Type; };
template <class T> struct List { typedef std::list<T> Type; };
template <class T> struct Vector { typedef std::vector<T> Type; };
template <class T> struct Deque { typedef std::deque<T> Type; };
template <class T> struct Set { typedef std::set<T> Type; };
template <class T> struct Stack { typedef std::stack<T> Type; };

// smart pointer
template <typename T>
class scoped_ptr
{
public:
    inline scoped_ptr() : m_object(new T) {}
    inline scoped_ptr(T* object) : m_object(object) {}
    inline ~scoped_ptr() { delete m_object; }
    inline operator T*() { return m_object; }
    inline operator const T*() const { return m_object; }
    inline T* operator->() { return m_object; }
    inline const T* operator->() const { return m_object; }
    inline T& operator*() { return *m_object; }
    inline const T& operator*() const { return *m_object; }
    inline T* get() { return m_object; }
    inline const T* get() const { return m_object; }
    inline void swap(scoped_ptr& t)
    {
	T* s = m_object;
	m_object = t.m_object;
	t.m_object = s;
    }
protected:
    T* m_object;
private:
    scoped_ptr(const scoped_ptr&);
    scoped_ptr& operator=(const scoped_ptr&);
    bool operator==(const scoped_ptr&);
    bool operator!=(const scoped_ptr&);
};
template <class T> struct ScopedPtr { typedef scoped_ptr<T> Type; };
template <class T> struct SharedPtr { typedef boost::shared_ptr<T> Type; };

// typical pimpl idiom
template <typename C> class Impl { public: C* __orig__; };
#define SH_DISABLE_COPY(C) C(const C&); C& operator=(const C&)
#define SH_DECLARE_IMPL(C) friend class C##Impl; ScopedPtr<C##Impl>::Type __impl__
#define SH_I(C) C##Impl* d = __impl__.get(); d->__orig__ = this
#define SH_E(C) C##Impl* d = __impl__.get()
#define SH_D(C) C##Impl* d = __impl__.get()
#define SH_Q(C) C* q = __orig__

// some useful macros
#define SH_NULL 0
#define SH_INLINE inline
#define SH_SAFE_DELETE(p) if (p) { delete p; p = NULL; }
#define SH_SAFE_ARRAY_DELETE(p) if (p) { delete[] p; p = NULL; }
#define SH_SAFE_LATER_DELETE(p) if (p) { p->deleteLater(); p = NULL; } // note: p must inherits QObject
#define SH_COUNTOF(a) (sizeof(a) / sizeof (a[0]))
#define SH_ASSERT(cond) Q_ASSERT(cond);

#endif // SHTO_DEFINES_H
